/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.logadaptor.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.StringTokenizer;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

import com.cqcis.uip.base.logadaptor.ObjectWriter;
/**
 * @author huangmy
 * @date   2008-4-11
 */
public class LogObjectAppender extends AppenderSkeleton {
	private static String QUIETPACKAGESPREFIXS_SPLIT = ","; // 分割包列表分割符号
	private static String DEFAULT_CONVERSION_PATTERN = "%d{yyyy-MM-dd HH:mm:ss}|%-5p|%t|%c %4L|%m%n";
    private ObjectWriter ow; // 对象目的
    private Level level; // 日志级别
    private boolean closed; // 是否已经关闭
    private boolean quieted; // 是否输出第三方包的日志
    private Collection<String> quietPackagesPrefixs;// 忽略包前缀列表
        
	public LogObjectAppender(ObjectWriter ow, String level, String conversionPattern, boolean quieted, String quietPackages) {
		if (ow == null) {
			throw new NullPointerException("the argument must not be null.");
		}
		
		this.ow = ow;
		if ("DEFAULT".equals(level)) {
			this.level = null;
		} else {
		    this.level = Level.toLevel(level);
		}
		conversionPattern = conversionPattern != null ? conversionPattern : DEFAULT_CONVERSION_PATTERN;
		super.setLayout(new PatternLayout(conversionPattern));
		this.quieted = quieted;
		
		if (quietPackages != null) {
			this.quietPackagesPrefixs = new ArrayList<String>();
			StringTokenizer st = new StringTokenizer(quietPackages, QUIETPACKAGESPREFIXS_SPLIT);
			while (st.hasMoreTokens()) {
				String pkgPrefix = st.nextToken();
				if (pkgPrefix != null) {
					pkgPrefix = pkgPrefix.trim();
				}
				
				if (pkgPrefix != null && pkgPrefix.length() > 0) {
					this.quietPackagesPrefixs.add(pkgPrefix);
				}
			}
		}
	}
	
	/**
	 * 判断是否增加
	 * 
	 * @param event
	 * @return
	 */
	private boolean isAppendTo(LoggingEvent event) {
		String loggerName = event.getLoggerName();		
		if (loggerName != null && this.quieted) {			
			if ((quietPackagesPrefixs == null || quietPackagesPrefixs.size() <= 0)
					&& !loggerName.startsWith("com.cqcis.")) {
				return false;// 忽略包前缀没有特别指定，则忽略所有的第三方包
			}
			
			if (quietPackagesPrefixs != null) {
				for (String p : quietPackagesPrefixs) {
					if (loggerName.startsWith(p)) {
						return false;
					}
				}
			}			
		}
		
		return true;
	}
	
	@Override
	protected void append(LoggingEvent event) {
		if (closed) {
			return;
		}
		
		if (!isAppendTo(event)) {// 是否增加
			return;
		}
		
		String log = this.layout.format(event);
		
		if (layout.ignoresThrowable()) {
			String[] s = event.getThrowableStrRep();
			if (s != null) {
				int len = s.length;
				for (int i = 0; i < len; i++) {
					log = log + s[i];
					log = log + Layout.LINE_SEP;
				}
			}
		}
		
		Level level = event.getLevel();
		if (getConfigLevel() == null) {
			this.ow.write(log);
		} else if (level.isGreaterOrEqual(getConfigLevel())) {
			this.ow.write(log);
		}		
	}
	
	private Level getConfigLevel() {		
		return this.level;
	}

	@Override
	public void close() {
		closed = true;
	}

	/**
	 * 需要layout
	 * 
	 */
	@Override
	public boolean requiresLayout() {		
		return true;
	}

}
